#pragma once

#include <optional>
#include <stdexcept>
#include <string>
#include <type_traits>

namespace compi
{

// 统一的结果代码枚举，用于表示操作的执行状态
enum class ResultCode
{
    Success,            // 操作成功完成
    MpiError,           // MPI调用失败
    InvalidRequest,     // 请求无效（如空实现指针）
    Cancelled,          // 操作被取消
    Timeout,            // 操作超时
    BufferError,        // 缓冲区相关错误
    SerializationError, // 序列化/反序列化错误
    NetworkError,       // 网络通信错误
    ResourceExhausted,  // 资源耗尽（如标签分配失败）
    Unknown             // 未知错误
};

// Result<T>模板类：类似Rust的Result类型，封装成功值或错误信息
// T: 成功时的返回值类型
template <typename T>
class Result
{
public:
    // 构造成功结果
    // 参数：value 成功时的值
    // 返回值：无
    // 异常：无
    static Result
    success(T value,
            const std::string & operation = "") noexcept(std::is_nothrow_move_constructible_v<T>)
    {
        return Result(std::move(value), operation);
    }

    // 构造成功结果（针对void特化）
    // 参数：无
    // 返回值：无
    // 异常：无

    // 构造错误结果
    // 参数：code 错误代码；message 可选的错误消息
    // 返回值：无
    // 异常：无
    static Result error(ResultCode code,
                        const std::string & message = "",
                        const std::string & operation = "") noexcept
    {
        return Result(code, message, operation);
    }

    // 检查是否为成功结果
    // 参数：无
    // 返回值：true表示成功，false表示错误
    // 异常：无
    bool is_success() const noexcept { return _is_success; }

    // 检查是否为错误结果
    // 参数：无
    // 返回值：true表示错误，false表示成功
    // 异常：无
    bool is_error() const noexcept { return !_is_success; }

    // 获取错误代码（仅在错误时有效）
    // 参数：无
    // 返回值：错误代码
    // 异常：无
    ResultCode error_code() const noexcept { return _error_code; }

    // 获取错误消息（仅在错误时有效）
    // 参数：无
    // 返回值：错误消息的常引用
    // 异常：无
    const std::string & error_message() const noexcept { return _error_message; }

    // 获取操作上下文名称（错误或成功场景下的描述）
    const std::string & operation() const noexcept { return _operation; }

    // 获取成功值（仅在成功时有效）
    // 参数：无
    // 返回值：成功值的常引用
    // 异常：当结果为错误时抛出std::runtime_error
    const T & value() const &
    {
        if (!_is_success)
            throw std::runtime_error("Attempted to access value of error result");
        return _value.value();
    }

    // 获取成功值（移动版本，仅在成功时有效）
    // 参数：无
    // 返回值：成功值的右值引用
    // 异常：当结果为错误时抛出std::runtime_error
    T && value() &&
    {
        if (!_is_success)
            throw std::runtime_error("Attempted to access value of error result");
        return std::move(_value.value());
    }

    // 获取成功值或默认值
    // 参数：default_value 当结果为错误时返回的默认值
    // 返回值：成功值或默认值
    // 异常：无
    T value_or(const T & default_value) const & noexcept(std::is_nothrow_copy_constructible_v<T>)
    {
        return _is_success ? _value.value() : default_value;
    }

    // 获取成功值或默认值（移动版本）
    // 参数：default_value 当结果为错误时返回的默认值
    // 返回值：成功值或默认值
    // 异常：无
    T value_or(T && default_value) && noexcept(std::is_nothrow_move_constructible_v<T>)
    {
        return _is_success ? std::move(_value.value()) : std::move(default_value);
    }

    // 布尔转换操作符：等价于is_success()
    // 参数：无
    // 返回值：true表示成功，false表示错误
    // 异常：无
    explicit operator bool() const noexcept { return _is_success; }

private:
    // 成功结果的私有构造函数
    explicit Result(T value,
                    const std::string & operation) noexcept(std::is_nothrow_move_constructible_v<T>)
        : _is_success(true),
          _value(std::move(value)),
          _error_code(ResultCode::Success),
          _operation(operation)
    {
    }

    // 错误结果的私有构造函数
    Result(ResultCode code, const std::string & message, const std::string & operation) noexcept
        : _is_success(false), _error_code(code), _error_message(message), _operation(operation)
    {
    }

    bool _is_success;
    std::optional<T> _value;
    ResultCode _error_code;
    std::string _error_message;
    std::string _operation;
};

// 引用类型特化：Result<T&>
// 注意：使用裸指针保存引用目标；错误时指针为nullptr。
template <typename T>
class Result<T &>
{
public:
    // 构造成功结果（引用）
    static Result success(T & value, const std::string & operation = "") noexcept
    {
        return Result(value, operation);
    }

    // 构造错误结果
    static Result error(ResultCode code,
                        const std::string & message = "",
                        const std::string & operation = "") noexcept
    {
        return Result(code, message, operation);
    }

    // 检查是否为成功结果
    bool is_success() const noexcept { return _is_success; }

    // 检查是否为错误结果
    bool is_error() const noexcept { return !_is_success; }

    // 获取错误代码（仅在错误时有效）
    ResultCode error_code() const noexcept { return _error_code; }

    // 获取错误消息（仅在错误时有效）
    const std::string & error_message() const noexcept { return _error_message; }

    // 获取操作上下文名称
    const std::string & operation() const noexcept { return _operation; }

    // 获取成功值（仅在成功时有效）
    const T & value() const &
    {
        if (!_is_success)
            throw std::runtime_error("Attempted to access value of error result");
        return *_value_ptr;
    }

    // 非const版本，便于可变访问
    T & value() &
    {
        if (!_is_success)
            throw std::runtime_error("Attempted to access value of error result");
        return *_value_ptr;
    }

    // 获取成功值或默认值
    T & value_or(T & default_value) const noexcept
    {
        return _is_success ? *_value_ptr : default_value;
    }

    // 布尔转换操作符：等价于is_success()
    explicit operator bool() const noexcept { return _is_success; }

private:
    // 成功结果的私有构造函数（引用）
    explicit Result(T & value, const std::string & operation) noexcept
        : _is_success(true),
          _value_ptr(&value),
          _error_code(ResultCode::Success),
          _operation(operation)
    {
    }

    // 错误结果的私有构造函数
    Result(ResultCode code, const std::string & message, const std::string & operation) noexcept
        : _is_success(false),
          _value_ptr(nullptr),
          _error_code(code),
          _error_message(message),
          _operation(operation)
    {
    }

    bool _is_success;
    T * _value_ptr;
    ResultCode _error_code;
    std::string _error_message;
    std::string _operation;
};

// void特化：用于不返回值的操作
template <>
class Result<void>
{
public:
    // 构造成功结果
    // 参数：无
    // 返回值：无
    // 异常：无
    static Result success(const std::string & operation = "") noexcept
    {
        return Result(true, operation);
    }

    // 构造错误结果
    // 参数：code 错误代码；message 可选的错误消息
    // 返回值：无
    // 异常：无
    static Result error(ResultCode code,
                        const std::string & message = "",
                        const std::string & operation = "") noexcept
    {
        return Result(code, message, operation);
    }

    // 检查是否为成功结果
    // 参数：无
    // 返回值：true表示成功，false表示错误
    // 异常：无
    bool is_success() const noexcept { return _is_success; }

    // 检查是否为错误结果
    // 参数：无
    // 返回值：true表示错误，false表示成功
    // 异常：无
    bool is_error() const noexcept { return !_is_success; }

    // 获取错误代码（仅在错误时有效）
    // 参数：无
    // 返回值：错误代码
    // 异常：无
    ResultCode error_code() const noexcept { return _error_code; }

    // 获取错误消息（仅在错误时有效）
    // 参数：无
    // 返回值：错误消息的常引用
    // 异常：无
    const std::string & error_message() const noexcept { return _error_message; }

    // 获取操作上下文名称
    const std::string & operation() const noexcept { return _operation; }

    // 布尔转换操作符：等价于is_success()
    // 参数：无
    // 返回值：true表示成功，false表示错误
    // 异常：无
    explicit operator bool() const noexcept { return _is_success; }

private:
    // 私有构造函数
    explicit Result(bool success, const std::string & operation) noexcept
        : _is_success(success), _error_code(ResultCode::Success), _operation(operation)
    {
    }

    Result(ResultCode code, const std::string & message, const std::string & operation) noexcept
        : _is_success(false), _error_code(code), _error_message(message), _operation(operation)
    {
    }

    bool _is_success;
    ResultCode _error_code;
    std::string _error_message;
    std::string _operation;
};

// 便利宏：创建成功结果
#define COMPI_SUCCESS(value) compi::Result<decltype(value)>::success(value)
#define COMPI_SUCCESS_WITH_OP(value, op) compi::Result<decltype(value)>::success(value, op)
#define COMPI_SUCCESS_VOID() compi::Result<void>::success()
#define COMPI_SUCCESS_VOID_OP(op) compi::Result<void>::success(op)

// 便利宏：创建错误结果
#define COMPI_ERROR(type, code, message) compi::Result<type>::error(code, message)
#define COMPI_ERROR_OP(type, code, message, op) compi::Result<type>::error(code, message, op)

} // namespace compi